package com.crack.spansframe;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.LeadingMarginSpan;
import android.text.style.ReplacementSpan;
import android.widget.TextView;

import com.crack.spansframe.extra.INeedTextView;

import java.lang.ref.WeakReference;

/**
 * 图片基类
 * Created by liuyu on 16-4-19.
 */
public class SpanImageSpan extends ReplacementSpan implements INeedTextView {
    public static final int ALIGN_BOTTOM = 0;

    public static final int ALIGN_BASELINE = 1;


    WeakReference<Drawable> mDrawableCache;

    TextView mTextView;

    String mSource;

    SpannableStringBuilder mSpan;

    Object mTag;

    int mSize;

    int mVerticalAlignment;

    int mMargin;

    private int maxWidth = 0;

    boolean mFlag = false;

    public Drawable getDrawable() {
        return getDrawableCache();
    }

    public void setDrawable(Drawable drawable) {
        mDrawableCache = new WeakReference<>(drawable);
        mFlag = true;
    }

    public SpanImageSpan(Drawable drawable) {
        this(null, drawable);
    }

    public SpanImageSpan(String source, SpannableStringBuilder spannableStringBuilder) {
        mVerticalAlignment = ALIGN_BOTTOM;
        mSource = source;
        mSpan = spannableStringBuilder;
    }

    public SpanImageSpan(String source, Drawable drawable) {
        mVerticalAlignment = ALIGN_BOTTOM;
        mDrawableCache = new WeakReference<>(drawable);
        this.mSource = source;
    }


    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
        Drawable d = getDrawableCache();

        if (maxWidth == 0 && mTextView != null) {
            Layout layout = mTextView.getLayout();
            if (layout != null) {
                maxWidth = layout.getWidth();
                if (text instanceof Spannable) {
                    Spannable spannable = (Spannable) text;
                    LeadingMarginSpan[] leadingSpans = spannable.getSpans(start, end, LeadingMarginSpan.class);
                    for (LeadingMarginSpan span : leadingSpans) {
                        mMargin += span.getLeadingMargin(true);
                    }
                    if (mMargin > 0) {
                        maxWidth -= 2 * mMargin;
                    }
                }
            }
        }

        if (maxWidth > 0) {
            final int width = d.getIntrinsicWidth();
            final int height = d.getIntrinsicHeight();
            if (width > maxWidth) {
                float scale = maxWidth * 1.0f / width;
                d.setBounds(0, 0, maxWidth, (int) (height * scale));
                mSize = maxWidth;
            } else if (width * 2 > maxWidth) {
                float scale = maxWidth * 1.0f / width;
                d.setBounds(0, 0, maxWidth, (int) (height * scale));
                mSize = maxWidth;
            } else {
                d.setBounds(0, 0, width, height);
                mSize = width;
            }
        } else {
            d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
        }
//        if (maxWidth > 0 && size > maxWidth) {
//            mSize = maxWidth;
//            float scale = size * 1.0f / maxWidth;
//            rect.set(rect.left, rect.top, mSize, (int) (rect.bottom / scale));
//            d.setBounds(rect);
//        } else {
//            mSize = size;
//        }

        Rect rect = d.getBounds();
        if (fm != null) {
            fm.ascent = -rect.bottom;
            fm.descent = 0;

            fm.top = fm.ascent;
            fm.bottom = 0;
        }
        return mSize;
    }


    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        if (maxWidth == 0) {
            mTextView.setText(mSpan);
        }

        Drawable b = getDrawableCache();
        canvas.save();

        int transY = bottom - b.getBounds().bottom;
        if (mVerticalAlignment == ALIGN_BASELINE) {
            transY -= paint.getFontMetricsInt().descent;
        }
        canvas.translate(x - mMargin / 2, transY);
        b.draw(canvas);
        canvas.restore();
    }

    private Drawable getDrawableCache() {
        if (mDrawableCache != null && mDrawableCache.get() != null) {
            return mDrawableCache.get();
        }

        Drawable drawable = getCache(mSource);
        if (drawable != null) {
            mDrawableCache = new WeakReference<>(drawable);
            mFlag = true;
            return drawable;
        }
        drawable = SpanSolve.sLoadingDrawable;
        mFlag = false;
        return drawable;
    }

    /**
     * 如果支持内存缓存，子类需重写此方法
     */
    protected Drawable getCache(String source) {
        return null;
    }

    @Override
    public void setTextView(TextView textView) {
        mTextView = textView;
        mTag = textView.getTag();
    }

}
